package com.cloudinnov.task.mq;

import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.core.ChannelAwareMessageListener;
import org.springframework.beans.factory.annotation.Autowired;

import com.alibaba.fastjson.JSON;
import com.cloudinnov.aop.SystemLog;
import com.cloudinnov.dao.ControlSolutionConfigDao;
import com.cloudinnov.dao.EquipmentsAttrDao;
import com.cloudinnov.dao.PredictionRuleTableDao;
import com.cloudinnov.dao.mongo.FireCRTEventMongoDBDao;
import com.cloudinnov.logic.ControlSolutionLogic;
import com.cloudinnov.logic.EquipmentsLogic;
import com.cloudinnov.logic.PredictionRuleLogLogic;
import com.cloudinnov.logic.PredictionRuleTableLogic;
import com.cloudinnov.model.ControlSolution;
import com.cloudinnov.model.ControlSolutionConfig;
import com.cloudinnov.model.Equipments;
import com.cloudinnov.model.EquipmentsAttr;
import com.cloudinnov.model.FireCRTEvent;
import com.cloudinnov.model.PredictionContacter;
import com.cloudinnov.model.PredictionRuleLog;
import com.cloudinnov.model.PredictionRuleTable;
import com.cloudinnov.utils.CodeUtil;
import com.cloudinnov.utils.CommonUtils;
import com.cloudinnov.utils.JudgeNullUtil;
import com.cloudinnov.websocket.ControlSolutionDialogueWebsocket;
import com.cloudinnov.websocket.PredictionAlarmWebsocket;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.rabbitmq.client.Channel;

/**
 * 监听rabbitMQ发过来的紧急电话数据
 * 
 * @ClassName: CallMQConsumer
 * @Description: TODO
 * @author: ningmeng
 * @date: 2016年12月8日 下午2:09:47
 */
public class FireMQConsumer implements ChannelAwareMessageListener {
	static final Logger LOG = LoggerFactory.getLogger(FireMQConsumer.class);
	public static final String ACCIDENTTYPE = "火灾";
	static final String DEFAULT_CHARSET = "UTF-8";
	static final long DELIVERIED_TAG = -1;
	
	@Autowired
	private ControlSolutionConfigDao controlSolutionConfigDao;
	@Autowired
	private EquipmentsAttrDao equipmentsAttrDao;
	@Autowired
	private AmqpTemplate faultTemplate;
	@Autowired
	private EquipmentsLogic equipmentsLogic;
	@Autowired
	private PredictionRuleTableDao predictionRuleTableDao;
	
	@SystemLog
	@Override
	public void onMessage(Message message, Channel channel) throws IOException {
		LOG.debug("enter FireMQConsumer OnMessage, data :{}", new String(message.getBody()));
		String receiveMsg = null;
		try {
			receiveMsg = new String(message.getBody(), DEFAULT_CHARSET);

			if (CommonUtils.isNotEmpty(receiveMsg)) {
				List<ControlSolutionConfig> data = null;
				FireCRTEvent fireEvent = JSON.parseObject(receiveMsg, FireCRTEvent.class);
				// fireCRTEventMongoDBDao.save(fireEvent);
				Map<String, Object> webSocketContent = new HashMap<String, Object>();
				if (CommonUtils.isEmpty(fireEvent.getDeviceId())) {
					LOG.error("FireCRT not is deviceID,please write deviceID, data: {}", fireEvent);
					CommonUtils.writeStringToFile(System.getProperty("catalina.base") + File.separator + "data"
							+ File.separator + "firedata.txt", receiveMsg + "\r\n");// 写入文件保存
					return;
				}
				EquipmentsAttr equAttr = new EquipmentsAttr();
				equAttr.setCustomTag(FireCRTEvent.DEVICE_ID);
				equAttr.setValue(fireEvent.getDeviceId());
				List<EquipmentsAttr> equAttrs = equipmentsAttrDao.selectEquipmentByCustomTagAndValue(equAttr);
				if (JudgeNullUtil.iList(equAttrs)) {// 查询设备所在的所有群控方案
					// 查询故障码，添加到故障队列，启动对应的情报板方案
					EquipmentsAttr equAttr_getvalue = new EquipmentsAttr();
					equAttr_getvalue.setCustomTag(FireCRTEvent.FAULT_CODE);
					equAttr_getvalue.setEquipmentCode(equAttrs.get(0).getEquipmentCode());
					equAttr_getvalue = equipmentsAttrDao.selectEquipmentByEquipmentCodeAndCustomTag(equAttr_getvalue);
					if (equAttr_getvalue != null) {
						//火灾预案中获取往websocket推送的数据
						Map<String, Object> firePlanWebSocketContent = new HashMap<String, Object>();
						String accidentCameraCode = "";
						//查询报警设备的位置信息
						Equipments alarmEquipment = equipmentsLogic.selectPositionByCode(equAttr_getvalue);
						alarmEquipment.setEquipmentName(alarmEquipment.getName());
						alarmEquipment.setAccidentType(ACCIDENTTYPE);
						//查询报警设备所处的区域,返回的是摄像机设备的信息
						Equipments cameraEquipment = equipmentsLogic.selectEquipArea(equAttr_getvalue);
						if (cameraEquipment != null) {
							accidentCameraCode = cameraEquipment.getCode();
						}
						
						//查询摄像机设备
						List<Equipments> cameraEquipmentsBySeCode = equipmentsLogic.selectCameraEquipmentsBySeCode();
						//获取隧道事故时的紧急联系人方式
						PredictionContacter predictionContacter = new PredictionContacter();
						List<PredictionContacter> predictionContacters = predictionRuleTableDao.selectPredictionContacter(predictionContacter);
						
						//websocket推送数据
						//返回事故类型
						firePlanWebSocketContent.put("accidentType", ACCIDENTTYPE);
						//往前端返回触发预案的设备信息
						firePlanWebSocketContent.put("predictionRules", alarmEquipment);
						//定位报警的摄像机的设备code值
						firePlanWebSocketContent.put("accidentCameraCode", accidentCameraCode);
						//摄像机分区和紧急联系人
						firePlanWebSocketContent.put("sectionsAndCameraEquipments", cameraEquipmentsBySeCode);
						firePlanWebSocketContent.put("predictionContacters", predictionContacters);
						
						ObjectMapper mapper1 = new ObjectMapper();
						mapper1.setSerializationInclusion(Include.NON_NULL);
						sendPredictionAlarmWebSocket(mapper1.writeValueAsString(firePlanWebSocketContent));
					    //对摄像头进行投屏,需要查询该摄像头的投屏动作
						switchCameraScreen();
			
					
						faultTemplate.convertAndSend(fireEvent.getEvent() + "," + equAttr_getvalue.getValue() + ","
							+ fireEvent.getDeviceId() + "," + fireEvent.getDevice() + "," + fireEvent.getPosition()
							+ "," + fireEvent.getOccurrenceTime());
					}
					fireEvent.setEquipmentCode(equAttrs.get(0).getEquipmentCode());
					fireEvent.setCategoryCode(equAttrs.get(0).getCategoryCode());
					ControlSolutionConfig record = new ControlSolutionConfig();
					record.setEquipmentCode(equAttrs.get(0).getEquipmentCode());
					List<ControlSolutionConfig> list = controlSolutionConfigDao.selectListByControlSolutionEquCode(record);
					List<ControlSolutionConfig.Config> configs;
					String solutionCode = null;
					for (ControlSolutionConfig controlSolutionConfig : list) {
						data = new ArrayList<>();
						solutionCode = controlSolutionConfig.getSolutionCode();
						List<ControlSolutionConfig> controlSolutionConfigs = controlSolutionConfigDao.selectListBySolutionCode(controlSolutionConfig);
						for (ControlSolutionConfig config : controlSolutionConfigs) {
							configs = new ArrayList<>();
							if (CommonUtils.isNotEmpty(config.getConfig())) {
								configs.addAll(JSON.parseArray(config.getConfig(), ControlSolutionConfig.Config.class));
							}
							if (JudgeNullUtil.iList(configs)) {
								config.setTextConfig(configs);
								data.add(config);
							}
						}
					}
					fireEvent.setSolutionCode(solutionCode);
					webSocketContent.put("data", fireEvent);
					webSocketContent.put("list", data);
					ObjectMapper mapper = new ObjectMapper();
					mapper.setSerializationInclusion(Include.NON_NULL);
					sendMesssageToDialogueWebSocket(mapper.writeValueAsString(webSocketContent));
				}
			}	
		} catch (UnsupportedEncodingException | JsonProcessingException e) {
			LOG.error("Subscribe fault data is error, data: {}, error: {}", message, e);
		} finally {
			long deliveryTag = message.getMessageProperties().getDeliveryTag();
			if (deliveryTag != DELIVERIED_TAG) {
				channel.basicAck(deliveryTag, false);
				message.getMessageProperties().setDeliveryTag(DELIVERIED_TAG);
				LOG.info("revice and ack msg: " + (receiveMsg == null ? message : receiveMsg));
			}
		}
	}

	public int sendMesssageToDialogueWebSocket(String content) {
		// 遍历所有连接客户工单WebSocket 推送对话
		Iterator<Map.Entry<String, ControlSolutionDialogueWebsocket>> controlSolutionDialogueWebsocket = ControlSolutionDialogueWebsocket.webSocketMap
				.entrySet().iterator();
		while (controlSolutionDialogueWebsocket.hasNext()) {
			Map.Entry<String, ControlSolutionDialogueWebsocket> controlSolutionDialogueEntry = controlSolutionDialogueWebsocket
					.next();
			try {
				controlSolutionDialogueEntry.getValue().sendMessage(content);

			} catch (IOException e) {
			}
		}
		return 0;
	}
	
	public int sendPredictionAlarmWebSocket(String content) {
		// 遍历所有连接客户工单WebSocket 推送对话
		Iterator<Map.Entry<String, PredictionAlarmWebsocket>> firePlanAlarmWebsocket = PredictionAlarmWebsocket.webSocketMap
				.entrySet().iterator();
		while (firePlanAlarmWebsocket.hasNext()) {
			Map.Entry<String, PredictionAlarmWebsocket> firePlanAlarm = firePlanAlarmWebsocket.next();
			try {
				firePlanAlarm.getValue().sendMessage(content);
			} catch (IOException e) {
			}
		}
		return 0;
	}
	
	/**
	 * 摄像头切屏方法
	 */
	public void switchCameraScreen() {
		
	}
	
}
